package dryven.model.di;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import dryven.annotations.DII;

public class DependencyInjectionIndicatorInjector implements DependencyInjector {

	private DependencyService _diService;
	
	public DependencyInjectionIndicatorInjector(DependencyService diService) {
		super();
		_diService = diService;
	}

	@Override
	public boolean appliesToType(Class<?> type, Annotation[] annotations) {
		for (Annotation annotation : annotations) {
			if(annotation.annotationType().equals(DII.class)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public Object load(LocalThreadStorage storage, Class<?> type, Annotation[] annotations) {
		DII dii = null;
		for (Annotation annotation : annotations) {
			if(annotation.annotationType().equals(DII.class)) {
				dii = (DII) annotation;
			}
		}
		Object o = _diService.getDependency(storage, dii.type(), new Annotation[]{});
		try {
			Method m = o.getClass().getMethod(dii.method(), new Class<?>[]{});
			if(!type.isAssignableFrom(m.getReturnType())) {
				throw new RuntimeException("DII getter and parameter type do not correspond");
			}
			return m.invoke(o, new Object[]{});
		} catch (Exception e) {
			throw new RuntimeException("Could not invoke DII getter method", e);
		}
	}

}
